package rigo.ricard.pris.rs.ac.uns.dmi.cars.bean;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;

import org.primefaces.context.RequestContext;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

import rigo.ricard.pris.rs.ac.uns.dmi.actions.InitAction;
import rigo.ricard.pris.rs.ac.uns.dmi.model.Advertising;
import rigo.ricard.pris.rs.ac.uns.dmi.model.CarPicture;
import rigo.ricard.pris.rs.ac.uns.dmi.service.AdvertisingLocalServiceUtil;
import rigo.ricard.pris.rs.ac.uns.dmi.service.CarPictureLocalServiceUtil;
import rigo.ricard.pris.rs.ac.uns.dmi.util.CurrentUser;

import com.liferay.counter.service.CounterLocalServiceUtil;
import com.liferay.portal.kernel.cache.CacheRegistryUtil;
import com.liferay.portal.kernel.dao.orm.Criterion;
import com.liferay.portal.kernel.dao.orm.DynamicQuery;
import com.liferay.portal.kernel.dao.orm.DynamicQueryFactoryUtil;
import com.liferay.portal.kernel.dao.orm.ProjectionFactoryUtil;
import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil;
import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.model.User;
import com.liferay.portlet.asset.model.AssetCategory;
import com.liferay.portlet.asset.model.AssetVocabulary;
import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
import com.liferay.portlet.asset.service.AssetVocabularyLocalServiceUtil;

@ManagedBean(name = "createCarBean")
@ViewScoped
public class CreateCarBean {
	
	private static final Log log = LogFactoryUtil.getLog(CreateCarBean.class);
	
	private Advertising advertising = null;
	
	private List<SelectItem> manufactures = null;
	private List<SelectItem> models = null;
	private List<CarPicture> carPictures = null;
	
	private boolean isEdit = false;
	
	long manufacturer = 0;
	long model = 0;
	
	public CreateCarBean() {
		init();
	}
	

	public void manufactureChange(ValueChangeEvent e) {
		selectModels((Long) e.getNewValue());
	}
	
	private void selectModels(long manufacturerId) {
		manufacturer = manufacturerId;
		models = new ArrayList<SelectItem>(0);
		models.add(new SelectItem(0, "--choose--"));
		try {
			for(AssetCategory ac : AssetCategoryLocalServiceUtil.getChildCategories(manufacturer)) {
				models.add(new SelectItem(ac.getCategoryId(), ac.getName()));
			}
		} catch (SystemException e1) {
			log.error("error in get child category for car : "+e1.getMessage());
		}
	}

	public void save() {
		try {
			//TODO modificate car pictures
			if(isEdit) {
				advertising.setModifiedDate(new Date());
			}
			else {
				advertising.setAdId(CounterLocalServiceUtil.increment());
				advertising.setCreateDate(new Date());
				for(CarPicture cp : carPictures) {
					cp.setAdId(advertising.getAdId());
					CarPictureLocalServiceUtil.updateCarPicture(cp, false);
				}
			}
			advertising.setCarManufacturerId(manufacturer);
			advertising.setCarModelId(model);
			User cuser =  CurrentUser.getCurrentUser(FacesContext.getCurrentInstance());
			if(cuser != null) {
				advertising.setUserId(cuser.getUserId());
				advertising.setUserName(cuser.getFullName());
			}
			AdvertisingLocalServiceUtil.updateAdvertising(advertising, !isEdit);
			FacesContext context = FacesContext.getCurrentInstance();
			CarsBean carsBean = (CarsBean) context.getViewRoot().getViewMap().get("carsBean");
			carsBean.init();
			RequestContext.getCurrentInstance().execute("createDlg.hide()");
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Advertising saved sucessfully", ""));
			log.info("advertising saved");
		} catch (Exception e) {
			log.error("error in saving advertising : "+e.getMessage());
			FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error occured", ""));
		}
	}
	
	public void handleFileUpload(FileUploadEvent event) {  
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();
        UploadedFile file = event.getFile();
        long carPicId = 0;
        try {
        carPicId = CounterLocalServiceUtil.increment();
        } catch (Exception e) {
			log.error("increment error!");
			return;
		}
        String fileName = String.valueOf(carPicId);
        //String path = externalContext.getRealPath("/");
        String path = "D:\\doc\\Faks\\PRIS\\workspace\\liferay-portal-6.1.1-ce-ga2\\tomcat-7.0.27\\webapps\\car-portlet\\images\\";
        File result = new File(path, fileName);
        if (!result.exists()) {
            System.out.println("The input file does not exist!");
        }
        try {
            File f = new File(path, fileName);
            if (f.createNewFile()) {
                System.out.println("File created.");
            } else {
                System.out.println("File could not be created.");
            }
        }catch (IOException e) { log.error("error create file : "+e.getMessage()); }
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(result);
            byte[] buffer = new byte[100000];
            int bulk;

            InputStream inputStream = event.getFile().getInputstream();

            while(true) {
                bulk = inputStream.read(buffer);
                if (bulk < 0) {
                    break;
                } 
                fileOutputStream.write(buffer, 0, bulk);
                fileOutputStream.flush();
            } 
            fileOutputStream.close();
            inputStream.close();
            CarPicture carPicture = CarPictureLocalServiceUtil.createCarPicture(carPicId);
            carPicture.setFileName(fileName);
            carPictures.add(carPicture);
         } catch (Exception e) {
             e.printStackTrace();
         }
    }  
	
	public void init() {
		isEdit = false;
		advertising = AdvertisingLocalServiceUtil.createAdvertising(0);
		carPictures = new ArrayList<CarPicture>();
		manufactures = new ArrayList<SelectItem>(0);
		manufactures.add(new SelectItem(0, "--choose--"));
		models = new ArrayList<SelectItem>(0);
		models.add(new SelectItem(0, "--choose--"));
		model = 0;
		manufacturer = 0;
		try {
			DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(AssetVocabulary.class);
			Criterion criterion = PropertyFactoryUtil.forName("name").eq(InitAction.VOCABULARY_NAME);
			dynamicQuery.add(criterion).setProjection(ProjectionFactoryUtil.property("vocabularyId"));
			List<Long> vocabularies = AssetVocabularyLocalServiceUtil.dynamicQuery(dynamicQuery);
	
			Long vocabularyId = -1L;
			if (vocabularies != null && vocabularies.size() > 0) {
				vocabularyId = vocabularies.get(0);
			}
			for(AssetCategory ac : AssetCategoryLocalServiceUtil.getVocabularyRootCategories(vocabularyId, 0, QueryUtil.ALL_POS, null)) {
				manufactures.add(new SelectItem(ac.getCategoryId(), ac.getName()));
			}
		} catch (Exception e) {
			log.error("error in constructor : "+e.getMessage());
		}
	}
	
	public void init(Advertising advertising) {
		isEdit = true;
		this.advertising = advertising;
		try {
			carPictures = CarPictureLocalServiceUtil.getCarPicturesByAdId(advertising.getAdId());
		} catch (SystemException e) {
			log.error("error car picture load : "+e.getMessage());
			carPictures = new ArrayList<CarPicture>();
		}
		manufacturer = advertising.getCarManufacturerId();
		model = advertising.getCarModelId();
		
		manufactures = new ArrayList<SelectItem>(0);
		manufactures.add(new SelectItem(0, "--choose--"));
		models = new ArrayList<SelectItem>(0);
		models.add(new SelectItem(0, "--choose--"));
		try {
			DynamicQuery dynamicQuery = DynamicQueryFactoryUtil.forClass(AssetVocabulary.class);
			Criterion criterion = PropertyFactoryUtil.forName("name").eq(InitAction.VOCABULARY_NAME);
			dynamicQuery.add(criterion).setProjection(ProjectionFactoryUtil.property("vocabularyId"));
			List<Long> vocabularies = AssetVocabularyLocalServiceUtil.dynamicQuery(dynamicQuery);
	
			Long vocabularyId = -1L;
			if (vocabularies != null && vocabularies.size() > 0) {
				vocabularyId = vocabularies.get(0);
			}
			for(AssetCategory ac : AssetCategoryLocalServiceUtil.getVocabularyRootCategories(vocabularyId, 0, QueryUtil.ALL_POS, null)) {
				manufactures.add(new SelectItem(ac.getCategoryId(), ac.getName()));
			}
		} catch (Exception e) {
			log.error("error in constructor : "+e.getMessage());
		}
		selectModels(manufacturer);
	}
	
	public String getPath(CarPicture cp) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
        ExternalContext externalContext = facesContext.getExternalContext();
        String retv = "/images/"+cp.getFileName();
        return retv;
	}

	public Advertising getAdvertising() {
		return advertising;
	}

	public void setAdvertising(Advertising advertising) {
		this.advertising = advertising;
	}

	public List<SelectItem> getManufactures() {
		return manufactures;
	}

	public void setManufactures(List<SelectItem> manufactures) {
		this.manufactures = manufactures;
	}

	public List<SelectItem> getModels() {
		return models;
	}

	public void setModels(List<SelectItem> models) {
		this.models = models;
	}

	public long getManufacturer() {
		return manufacturer;
	}

	public void setManufacturer(long manufacturer) {
		this.manufacturer = manufacturer;
	}
	
	public long getModel() {
		return model;
	}
	
	public void setModel(long model) {
		this.model = model;
	}


	public boolean isEdit() {
		return isEdit;
	}


	public void setEdit(boolean isEdit) {
		this.isEdit = isEdit;
	}


	public List<CarPicture> getCarPictures() {
		return carPictures;
	}


	public void setCarPictures(List<CarPicture> carPictures) {
		this.carPictures = carPictures;
	}
	
}
